https://github.com/linwu-hi/code-interview/issues/2

<!-- preDependencies  -->
preDependencies（或称为peerDependencies）是指组件库对于其他依赖的版本要求
它用于指定组件库所依赖的其他库或框架的版本范围，以确保组件库与这些依赖的兼容性

<!-- 为什么需要二次封装组件库 -->
统一风格：在一个大的项目或者多个相关的项目中，保持一致的界面风格和交互方式是非常重要的。
通过二次封装，我们可以定义统一的样式和行为，减少不一致性。

降低维护成本：当底层的组件库更新时，我们可能需要在项目的多个地方进行修改。
但是如果我们有了自己的封装，只需要在封装层面进行更新即可，这大大降低了维护成本。

增加定制功能：有些时候，我们需要在原有组件库的基础上增加一些特定的功能，
如特定的验证、错误处理等。二次封装提供了这样的可能。

提高开发效率：在一些常用的功能（如表单验证、全局提示等）上，二次封装可以提供更方便的API，提高开发效率。

<!-- 如何对一个组件库进行测试? -->
一类是针对组件本身的功能和性能的测试（例如，单元测试、性能测试），
另一类是针对组件在集成环境下的行为和性能的测试（例如，集成测试、系统测试）。

<!-- 组件库如何实现在线主题定制的? -->
1. 使用 CSS 变量定义样式
将组件的样式使用 CSS 变量定义,这样可以通过改变 CSS 变量的值来修改样式。

:root {
  --primary-color: #1890ff;
}

.btn {
  background: var(--primary-color); 
}

2. 提供主题文件进行配置
让用户可以通过导入自定义的主题文件来覆盖默认样式。

// theme.js
export default {
  '--primary-color': '#409eff'
}

3. 在线主题编辑器
提供一个在线工具,用户可以在工具中配置主题,生成主题文件。
工具会提交主题配置,服务器端接收后动态编译生成新的样式,并返回给前端。

4. 前端应用新样式
前端通过加载服务器返回的 CSS 文件来应用新的主题样式,实现样式更新而无需重新打包。

// 请求主题文件
fetchTheme(theme).then(css => {
  // 动态创建style标签,插入css
  const style = document.createElement('style');
  style.innerHTML = css;
  document.head.appendChild(style);  
})

5. 持久化主题配置
将用户主题配置持久化本地存储,这样每次访问都可以应用上次选定的主题。

<!-- 组件库的类型定义应该怎样设计? -->
1. 定义全局类型 versus 定义组件Props类型
在组件库中，我们经常需要定义一些可以在多个组件之间共享的全局类型，以及针对特定组件的props类型。例如：

// 全局类型
export interface Size {
  width: number;
  height: number;
}

// 组件Props类型
export interface ButtonProps {
  size?: Size;
  label: string;
  onClick?: () => void;
}

2. 类型导出应该集中还是分散?
对于小型库，可以在一个单独的文件中集中导出所有类型
对于大型库，可能需要将类型定义分散在各个组件文件中，然后在一个单独的文件中重新导出它们

<!-- 组件库的渐进升级策略应该怎么设计? -->
1. 版本控制策略
例如，版本号为 1.2.3 表示主版本号为 1，次版本号为 2，补丁版本号为 3。

主版本号（Major）: 当你做了不兼容的 API 修改
次版本号（Minor）: 当你做了向下兼容的功能性新增
补丁版本号（Patch）: 当你做了向下兼容的问题修复

2. 向下兼容处理
向下兼容性是指在升级组件库时，保证新版本不会破坏旧版本的功能
在进行不向下兼容的变化时，应在主版本号上进行增加，以警告用户可能需要修改他们的代码。

3. 功能被废弃怎么通知用户升级?
应在库的文档、更新日志以及相关的 API 文档中明确注明。
在代码中，可以通过添加警告或者错误信息来提醒用户：

4. 兼容旧版本的方案
一种常见的策略是在主版本升级后，继续维护旧版本的一个分支